package jmind.asteroidea.registry;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import jmind.asteroidea.annotations.Starfish;
import jmind.asteroidea.core.StarfishSpec;
import jmind.asteroidea.plugin.spring.SpringBeanUtil;

import java.util.List;
import java.util.Map;
import java.util.Set;

import static java.util.stream.Collectors.toList;

/**
 * description: 接口方法注册
 *
 * @author weibo.xie
 * @date:2022/7/12 上午11:26
 */
public class StarfishRegistry {
     /***接口名---》 （tag，实现类描述 ）**/
     private  final Map<String, Map<String, StarfishSpec>>  registerStarfishInterface;

        private static class StarfishRegistryHolder {
            private static final StarfishRegistry INSTANCE = new StarfishRegistry();
        }
        private StarfishRegistry (){registerStarfishInterface= Maps.newHashMap();}
        public static final StarfishRegistry getInstance() {
            return StarfishRegistryHolder.INSTANCE;
        }

        public void register(Class interfaceClass, Set<Class> subtypes){
            Map<String,StarfishSpec> implMap=Maps.newHashMap();
            for (Class subClass : subtypes) {
                Starfish starfish = (Starfish) subClass.getAnnotation(Starfish.class);
                //  没有注解的不注册
                if(starfish==null){
                     continue;
                }
                StarfishSpec starfishSpec=new StarfishSpec();
                starfishSpec.setBeanName(starfish.value().isEmpty()? SpringBeanUtil.getBeanName(subClass):starfish.value());
                starfishSpec.setTag(starfish.tag());
                starfishSpec.setImplClass(subClass);
                starfishSpec.setOrder(starfish.order());
                implMap.put(starfish.tag(),starfishSpec);
            }
            registerStarfishInterface.put(interfaceClass.getName(),implMap);

        }

        public StarfishSpec  getStarfishSpec(Class interfaceClass,String tag){
            Map<String, StarfishSpec> stringStarfishSpecMap = registerStarfishInterface.get(interfaceClass.getName());
            if(stringStarfishSpecMap!=null){
                return stringStarfishSpecMap.get(tag);
            }
            return null;
        }

        public List<StarfishSpec> getStarfishSpec(Class interfaceClass,String[] tags){
            Map<String, StarfishSpec> specMap = registerStarfishInterface.get(interfaceClass.getName());
            // 数组为空取全部实例
            if(tags==null || tags.length==0){
                return specMap.values().stream().sorted().collect(toList());
            }
            List<StarfishSpec> list= Lists.newArrayList();
            for(String tag:tags){
                StarfishSpec spec = specMap.get(tag);
                if(spec!=null){
                    list.add(spec);
                }
            }
            return list;
        }

        @Override
        public String toString(){
            return  registerStarfishInterface.toString();
        }
}
